package de.fhhannover.inform.itteam.snmpnetviz;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import de.fhhannover.inform.itteam.snmpnetviz.gui.LoadingWindow;

public class NetworkTreeFactory {
	private String[][] switchConnections;
	private IpToMac mIpToMac = new IpToMac();
	private LoadingWindow mLoadingWindow;
	
	public NetworkTreeFactory(String switches, LoadingWindow loadingWindow) {
		mLoadingWindow = loadingWindow;
		
		String[] connectionStrings = switches.split(";");
		
		mLoadingWindow.setStatusText("Parsing switches property...");
		
		// Load the switches and their connections from string
		switchConnections = new String[connectionStrings.length][2];
		for (int i=0;i<connectionStrings.length;i++) {
			String[] split = connectionStrings[i].split(">");
			if (split.length>1) {
				switchConnections[i][0]=split[0];
				switchConnections[i][1]=split[1];
			}
			else {
				switchConnections[i][0]="";
				switchConnections[i][1]=split[0];
			}
			
		}
	}
	
	public HostEntry buildTree() {
		ExecutorService executor = new snmpExecutor();
		ArrayList<Future<IpToMac>> futures = new ArrayList<Future<IpToMac>>();
		
		mLoadingWindow.setStatusText("Start reading of the big IP to MAC table...");
		
		// build IP to MAC Table locally with use of all configured switches
		for (String[] currentSwitch : switchConnections) {
			futures.add(executor.submit(new snmpIpMacTableCallable(currentSwitch[1],mLoadingWindow)));
		}
		
		// merge all ip tables from the switches to one global one
		Iterator<Future<IpToMac>> fIT=futures.iterator();
		while (fIT.hasNext()) {
			try {
				Future<IpToMac> next = fIT.next();
				IpToMac ipMac = next.get();
				mIpToMac.addIpMacTable(ipMac);
			} catch (InterruptedException e) {
				e.printStackTrace();
			} catch (ExecutionException e) {
				e.printStackTrace();
			}
		}
		
		// get the SNMP Port Table for for the first switch and parse it to the tree
		if (switchConnections.length>0) {
			HostEntry switchEntry = new HostEntry(switchConnections[0][1]);
			return getSwitchTree(switchEntry);
		}
		
		return null;
	}
	
	private HostEntry getSwitchTree(HostEntry switchEntry) {
		mLoadingWindow.setStatusText("Start reading of the big node tree...");
		
		ExecutorService executor = new snmpExecutor();
		executor.submit(new SnmpSwitchCallable(switchEntry,switchConnections,mIpToMac,mLoadingWindow));
		executor.shutdown();
		try {
			executor.awaitTermination(1, TimeUnit.HOURS);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		return switchEntry;		
	}
}
